package org.protege.owl.examples.tab.grammar;
// Driver do remote-debuggingu dla ANTLR i gramatyki jezyka naturalnego

import java.io.FileInputStream;
import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
import org.protege.owl.examples.tab.ErrorLogger;
import org.protege.owl.examples.tab.InstanceSet;
import org.protege.owl.examples.tab.PredicateRegistry;
import org.protege.owl.examples.tab.ResultTable;
import org.protege.owl.examples.tab.VariableRegistry;

public class FOLAnalyzer
{
	public void setEnvironment(PredicateRegistry pr, VariableRegistry vr)
	{
		predicateRegistry = pr;
		variableRegistry = vr;
	}
	
	public ResultTable getResultTable()
	{
		return resultTable;
	}
	
	public void query(String queryString)
	{
		try
		{	
			// Stage 1 - remove unnecesary whitespace and newlines
			String clean1 = stage1(queryString);
			System.out.println(clean1);
			
			// Stage 2 - construct statement's AST
			CommonTreeNodeStream nodes2 = stage2(clean1);
			
			// Stage 3 - parse AST - push down negation
			CommonTreeNodeStream nodes3 = stage3(nodes2);
			
			// Stage 4 - final stage
			CommonTreeNodeStream nodes4 = stage4(nodes3);
		}
		catch (Exception e)
		{
			System.err.println("Ooopppsss... Something is pretty wrong:");
			e.printStackTrace();
		}
	}
	
	private String stage1(String inputString)
	{
		try
		{
			CommonTokenStream tokens = new CommonTokenStream();
			ANTLRStringStream input = new ANTLRStringStream(inputString);
			FOLStage1Lexer stage1Lexer = new FOLStage1Lexer(input);
			tokens.setTokenSource(stage1Lexer);
			FOLStage1Parser stage1Parser = new FOLStage1Parser(tokens);
			return stage1Parser.stat();
		}
		catch(Exception e)
		{
			System.err.println("Exception at stage 1:");
			ErrorLogger.log(e);
			e.printStackTrace();
		}
		return "";
	}
	
	private CommonTreeNodeStream stage2(String cleanInput)
	{
		try
		{
			CommonTokenStream tokens = new CommonTokenStream();
			ANTLRStringStream input = new ANTLRStringStream(cleanInput);
			FOLStage2Lexer stage2Lexer = new FOLStage2Lexer(input);
			tokens.setTokenSource(stage2Lexer);
			FOLStage2Parser stage2Parser = new FOLStage2Parser(tokens);
			FOLStage2Parser.stat_return stat = stage2Parser.stat();
			CommonTree tree = (CommonTree) stat.getTree();
			CommonTreeNodeStream nodes = new CommonTreeNodeStream(tree);
			return nodes;
		}
		catch(Exception e)
		{
			System.err.println("Exception at stage 2:");
			ErrorLogger.log(e);
			e.printStackTrace();
		}
		return null;
	}
	
	private CommonTreeNodeStream stage3(CommonTreeNodeStream nodeStream)
	{
		try
		{
			FOLStage3 walker = new FOLStage3(nodeStream);
			FOLStage3.stat_return stat = walker.stat();

			CommonTree tree = (CommonTree) stat.getTree();
			CommonTreeNodeStream nodes = new CommonTreeNodeStream(tree);
			return nodes;
		}
		catch(Exception e)
		{
			System.err.println("Exception at stage 3:");
			ErrorLogger.log(e);
			e.printStackTrace();
		}
		return null;
	}
	
	private CommonTreeNodeStream stage4(CommonTreeNodeStream nodeStream)
	{
		try
		{
			FOLStage4 walker = new FOLStage4(nodeStream);
			variableRegistry.clear();
			walker.setEnvironment(predicateRegistry, variableRegistry);
			FOLStage4.stat_return stat = walker.stat();
			resultTable = walker.getResultTable();

			CommonTree tree = (CommonTree) stat.getTree();
			CommonTreeNodeStream nodes = new CommonTreeNodeStream(tree);
			return nodes;
		}
		catch(Exception e)
		{
			System.err.println("Exception at stage 4:");
			ErrorLogger.log(e);
			e.printStackTrace();
		}
		return null;
	}
	
	// Predicate registry
	private PredicateRegistry predicateRegistry;
	// Variable registry
	private VariableRegistry variableRegistry;
	
	// Sample instance set
	private ResultTable resultTable;
}